Opengl ES 2.0中如何描画点线?
Opengl ES 2.0中如何描画点线?
在Opengl中可以使用line stipple标志来描画点线,但是在Opengl ES中,line stipple标志已经被裁减了,没有了,所以在Opengl ES 2.0中,想要描画点线,应该如何实现,有没有性能上比较好的方法?
[解决办法]
我自己写了个点线的描画算法,给大家贴出来!!!
OnTestLineStipple是入口函数,这里指写了算法,具体画线的Opengl ES 函数被封装了,没有贴出来。
int makeLineStipplePoint(
intiStippleDistance,
void*pvBuffer,
intiBufferSize,
char*pcFlagBufferSize,
int*piPointCount,
intsize,
intiDimension,
void*pvPointer
)
{
short* pPoint = pvPointer;
short* pBuffer = pvBuffer;
int iBufferIndxe = 0;
float fDistance,fDistDiff,xNormalizeVector,yNormalizeVector;
float fDistanceTmp = iStippleDistance;
int x,y,xBase,yBase;
int xPre = 0xfffffff;
int yPre = xPre;
int iFlagBufferIndex = 0;
char cFlagBufferBitIndex = 0x80;
char cIsDraw = 0xff;
if( ( NULL == pvBuffer ) || ( NULL == pcFlagBufferSize ) || ( NULL == pvPointer ) )
{
return -1;
}
iBufferSize /= (size * iDimension);
xBase = x = *pPoint;
yBase = y = *(pPoint+1);
pBuffer[iBufferIndxe++] = *pPoint++;
pBuffer[iBufferIndxe++] = *pPoint++;
if(iDimension == 3)
{
pBuffer[iBufferIndxe++] = *pPoint++;
}
(*piPointCount)--;
x -= *pPoint;
y -= *(pPoint+1);
while( ( --iBufferSize ) && (*piPointCount) )
{
fDistance = sqrtf( x * x + y * y );
fDistDiff = fDistance - fDistanceTmp;
if( fDistDiff < -1.0f )
{
//插入已有点的分支
xBase = x = *pPoint;
yBase = y = *(pPoint+1);
pBuffer[iBufferIndxe++] = *pPoint++;
pBuffer[iBufferIndxe++] = *pPoint++;
if(iDimension == 3)
{
pBuffer[iBufferIndxe++] = *pPoint++;
}
(*piPointCount)--;
memcpy( &pBuffer[iBufferIndxe], &pBuffer[iBufferIndxe-iDimension], (size * iDimension) );
iBufferIndxe += iDimension;
--iBufferSize;
x -= *pPoint;
y -= *(pPoint+1);
pcFlagBufferSize[iFlagBufferIndex] = cFlagBufferBitIndex & cIsDraw;
fDistanceTmp -= fDistance;
}
else if( fDistDiff > 1.0f )
{
//插入新点的分支
int iXFlag = ( x >= 0 ) ? -1 : 1;
int iYFlag = ( y >= 0 ) ? -1 : 1;
if( xPre != x )
{
xPre = x;
xNormalizeVector = abs((float)x) / fDistance * iXFlag;
xNormalizeVector *= fDistanceTmp;
}
if( yPre != y )
{
yPre = y;
yNormalizeVector = abs((float)y) / fDistance * iYFlag;
yNormalizeVector *= fDistanceTmp;
}
xBase += AROUND(xNormalizeVector);
yBase += AROUND(yNormalizeVector);
pBuffer[iBufferIndxe++] = xBase;
pBuffer[iBufferIndxe++] = yBase;
if(iDimension == 3)
{
pBuffer[iBufferIndxe++] = pBuffer[iBufferIndxe-3];
}
pcFlagBufferSize[iFlagBufferIndex] = cFlagBufferBitIndex & cIsDraw;
cIsDraw = ~cIsDraw;
x = xBase - *pPoint;
y = yBase - *(pPoint+1);
fDistanceTmp = iStippleDistance;
}
else//( fDistance == fDistanceTmp )
{
xBase = x = *pPoint;
yBase = y = *(pPoint+1);
pBuffer[iBufferIndxe++] = *pPoint++;
pBuffer[iBufferIndxe++] = *pPoint++;
if(iDimension == 3)
{
pBuffer[iBufferIndxe++] = *pPoint++;
}
(*piPointCount)--;
x -= *pPoint;
y -= *(pPoint+1);
pcFlagBufferSize[iFlagBufferIndex] = cFlagBufferBitIndex & cIsDraw;
cIsDraw = ~cIsDraw;
fDistanceTmp = iStippleDistance;
}
}
if( (*piPointCount) < iBufferSize )
{
return iBufferSize;
}
return 0;
}
int drawLineStipple( ESShader *pesShader, int iFactor, unsigned short usPattern, int iPointCount, int size, int iDimension, void* pvPointer )
{
static short asDestBuffer[1024] = {0};
static char acFlagBuffer[1024/((2*2)*8)] = {0};
int RemainPointNum = 0;
int iPointCountTmp = iPointCount;
int iLength1 = 0;
int iLoop;
//根据Pattern制作点线线长
for( iLoop = 0; iLoop < 16; ++iLoop )
{
int iValue = 1;
if( usPattern & ( iValue << iLoop ) )
{
iLength1 += iFactor;
}
else
{
if( iLength1 )
{
break;
}
}
}
//描画点线
while( iPointCount )
{
memset( asDestBuffer, 0, sizeof(asDestBuffer) );
RemainPointNum = makeLineStipplePoint( iLength1, (void*)asDestBuffer, sizeof(asDestBuffer), acFlagBuffer,
&iPointCount, size, iDimension, pvPointer );
esDrawPolyLines( pesShader, ( (sizeof(asDestBuffer)/(size*iDimension)) - RemainPointNum ), asDestBuffer, NULL );
if( iPointCount )
{
memcpy( pvPointer, (pvPointer+((iPointCountTmp-iPointCount)*iDimension*size)), size*iPointCount*iDimension );
continue;
}
}
return 0;
}
void OnTestLineStipple( void *pArg )
{
unsigned short usPoints4[] = { 50,81, 150,176, 250,81, 270,81, 350,81, 352,81, 362,81, 366,81, 370,81, 370,81, 370,81, 370,81, 375,81, 380,81, 385,81, 390,81, 395,81, 400,81, 400,81 };
esSetDrawColor(pesShader,0,255,0,255);
esSetLineWidth(pesShader,3);
drawLineStipple( pesShader, 1, 0xff00, sizeof(usPoints4)/(sizeof(usPoints4[0])*2), sizeof(usPoints4[0])/*一个坐标的size*/, 2/*维数*/, (void*)usPoints4 );
}