📄 dgl.cc
字号:
U32 n,
const ColorI* colorTable,
const U32 maxColorIndex,
F32 rot,
bool bUTF16)
{
// return on zero length strings
if( n < 1 )
return ptDraw.x;
PROFILE_START(DrawText);
MatrixF rotMatrix( EulerF( 0.0, 0.0, mDegToRad( rot ) ) );
Point3F offset( ptDraw.x, ptDraw.y, 0.0 );
Point3F points[4];
U32 nCharCount = 0;
Point2I pt;
UTF16 c;
const UTF8 *str = (const UTF8*)in_string;
const UTF8 *endStr = str + n;
pt.x = 0;
ColorI currentColor;
S32 currentPt = 0;
TextureObject *lastTexture = NULL;
currentColor = sg_bitmapModulation;
FrameTemp<TextVertex> vert(4*n);
glDisable(GL_LIGHTING);
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glEnableClientState ( GL_VERTEX_ARRAY );
glVertexPointer ( 2, GL_FLOAT, sizeof(TextVertex), &(vert[0].p) );
glEnableClientState ( GL_COLOR_ARRAY );
glColorPointer ( 4, GL_UNSIGNED_BYTE, sizeof(TextVertex), &(vert[0].c) );
glEnableClientState ( GL_TEXTURE_COORD_ARRAY );
glTexCoordPointer ( 2, GL_FLOAT, sizeof(TextVertex), &(vert[0].t) );
// first build the point, color, and coord arrays
/// Chinese
#ifdef TGE_CHINESE
for (; str < endStr; str++)//c = *(++str))
{
if(bUTF16)
{
c = *(UTF16*)str++;
}
else
c = GBSTEP(str);
#else
U32 i;
FrameTemp<UTF16> ubuf(dStrlen(str) + 1);
convertUTF8toUTF16(str, ubuf, dStrlen(str) + 1);
for(i = 0,c = ubuf[i];ubuf[i] && i < n;i++,c = ubuf[i])
{
#endif
nCharCount++;
if(nCharCount > n)
break;
// We have to do a little dance here since \t = 0x9, \n = 0xa, and \r = 0xd
if ((c >= 1 && c <= 7) ||
(c >= 11 && c <= 12) ||
(c == 14))
{
// Color code
if (colorTable)
{
static U8 remap[15] =
{
0x0, // 0 special null terminator
0x0, // 1 ascii start-of-heading??
0x1,
0x2,
0x3,
0x4,
0x5,
0x6,
0x0, // 8 special backspace
0x0, // 9 special tab
0x0, // a special \n
0x7,
0x8,
0x0, // a special \r
0x9
};
U8 remapped = remap[c];
// Ignore if the color is greater than the specified max index:
if ( remapped <= maxColorIndex )
{
const ColorI &clr = colorTable[remapped];
sg_bitmapModulation = clr;
currentColor = clr;
}
}
continue;
}
// reset color?
if ( c == 15 )
{
currentColor = sg_textAnchorColor;
sg_bitmapModulation = sg_textAnchorColor;
continue;
}
// push color:
if ( c == 16 )
{
sg_stackColor = sg_bitmapModulation;
continue;
}
// pop color:
if ( c == 17 )
{
currentColor = sg_stackColor;
sg_bitmapModulation = sg_stackColor;
continue;
}
// Tab character
if ( c == dT('\t') )
{
const PlatformFont::CharInfo &ci = font->getCharInfo( dT(' ') );
pt.x += ci.xIncrement * GFont::TabWidthInSpaces;
continue;
}
if( !font->isValidChar( c ) )
continue;
const PlatformFont::CharInfo &ci = font->getCharInfo(c);
TextureObject *newObj = font->getTextureHandle(ci.bitmapIndex);
if(newObj != lastTexture)
{
if(currentPt)
{
glBindTexture(GL_TEXTURE_2D, lastTexture->texGLName);
glDrawArrays( GL_QUADS, 0, currentPt );
currentPt = 0;
}
lastTexture = newObj;
}
if(ci.width != 0 && ci.height != 0)
{
pt.y = font->getBaseline() - ci.yOrigin;
pt.x += ci.xOrigin;
F32 texLeft = F32(ci.xOffset) / F32(lastTexture->texWidth);
F32 texRight = F32(ci.xOffset + ci.width) / F32(lastTexture->texWidth);
F32 texTop = F32(ci.yOffset) / F32(lastTexture->texHeight);
F32 texBottom = F32(ci.yOffset + ci.height) / F32(lastTexture->texHeight);
F32 screenLeft = pt.x;
F32 screenRight = pt.x + ci.width;
F32 screenTop = pt.y;
F32 screenBottom = pt.y + ci.height;
points[0] = Point3F(screenLeft, screenBottom, 0.0);
points[1] = Point3F(screenRight, screenBottom, 0.0);
points[2] = Point3F( screenRight, screenTop, 0.0);
points[3] = Point3F( screenLeft, screenTop, 0.0);
for( int i=0; i<4; i++ )
{
rotMatrix.mulP( points[i] );
points[i] += offset;
}
vert[currentPt++].set(points[0].x, points[0].y, texLeft, texBottom, currentColor);
vert[currentPt++].set(points[1].x, points[1].y, texRight, texBottom, currentColor);
vert[currentPt++].set(points[2].x, points[2].y, texRight, texTop, currentColor);
vert[currentPt++].set(points[3].x, points[3].y, texLeft, texTop, currentColor);
pt.x += ci.xIncrement - ci.xOrigin;
}
else
pt.x += ci.xIncrement;
}
if(currentPt)
{
glBindTexture(GL_TEXTURE_2D, lastTexture->texGLName);
glDrawArrays( GL_QUADS, 0, currentPt );
}
glDisableClientState ( GL_VERTEX_ARRAY );
glDisableClientState ( GL_COLOR_ARRAY );
glDisableClientState ( GL_TEXTURE_COORD_ARRAY );
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
pt.x += ptDraw.x; //*** DAW: Account for the fact that we removed the drawing point from the text start at the beginning.
AssertFatal(pt.x >= ptDraw.x, "How did this happen?");
PROFILE_END();
return pt.x - ptDraw.x;
}
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- //
// Drawing primitives
void dglDrawLine(S32 x1, S32 y1, S32 x2, S32 y2, const ColorI &color)
{
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_TEXTURE_2D);
glColor4ub(color.red, color.green, color.blue, color.alpha);
glBegin(GL_LINES);
glVertex2f((F32)x1 + 0.5, (F32)y1 + 0.5);
glVertex2f((F32)x2 + 0.5, (F32)y2 + 0.5);
glEnd();
glBegin(GL_POINTS);
glVertex2f((F32)x2 + 0.5, (F32)y2 + 0.5);
glEnd();
}
void dglDrawLine(const Point2I &startPt, const Point2I &endPt, const ColorI &color)
{
dglDrawLine(startPt.x, startPt.y, endPt.x, endPt.y, color);
}
void dglDrawRect(const Point2I &upperL, const Point2I &lowerR, const ColorI &color)
{
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_TEXTURE_2D);
glColor4ub(color.red, color.green, color.blue, color.alpha);
glBegin(GL_LINE_LOOP);
glVertex2f((F32)upperL.x + 0.5, (F32)upperL.y + 0.5);
glVertex2f((F32)lowerR.x + 0.5, (F32)upperL.y + 0.5);
glVertex2f((F32)lowerR.x + 0.5, (F32)lowerR.y + 0.5);
glVertex2f((F32)upperL.x + 0.5, (F32)lowerR.y + 0.5);
glEnd();
}
// the fill convention for lined rects is that they outline the rectangle border of the
// filled region specified.
void dglDrawRect(const RectI &rect, const ColorI &color)
{
Point2I lowerR(rect.point.x + rect.extent.x - 1, rect.point.y + rect.extent.y - 1);
dglDrawRect(rect.point, lowerR, color);
}
// the fill convention says that pixel at upperL will be filled and
// that pixel at lowerR will NOT be filled.
void dglDrawRectFill(const Point2I &upperL, const Point2I &lowerR, const ColorI &color)
{
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_TEXTURE_2D);
glColor4ub(color.red, color.green, color.blue, color.alpha);
glRecti((S32)upperL.x, (S32)upperL.y, (S32)lowerR.x, (S32)lowerR.y);
}
void dglDrawRectFill(const RectI &rect, const ColorI &color)
{
Point2I lowerR(rect.point.x + rect.extent.x, rect.point.y + rect.extent.y);
dglDrawRectFill(rect.point, lowerR, color);
}
void dglDraw2DSquare( const Point2F &screenPoint, F32 width, F32 spinAngle )
{
width *= 0.5;
MatrixF rotMatrix( EulerF( 0.0, 0.0, spinAngle ) );
Point3F offset( screenPoint.x, screenPoint.y, 0.0 );
Point3F points[4];
points[0] = Point3F(-width, -width, 0.0);
points[1] = Point3F(-width, width, 0.0);
points[2] = Point3F( width, width, 0.0);
points[3] = Point3F( width, -width, 0.0);
for( int i=0; i<4; i++ )
{
rotMatrix.mulP( points[i] );
points[i] += offset;
}
glBegin(GL_TRIANGLE_FAN);
glTexCoord2f(0.0, 0.0);
glVertex2fv(points[0]);
glTexCoord2f(0.0, 1.0);
glVertex2fv(points[1]);
glTexCoord2f(1.0, 1.0);
glVertex2fv(points[2]);
glTexCoord2f(1.0, 0.0);
glVertex2fv(points[3]);
glEnd();
}
void dglDrawBillboard( const Point3F &position, F32 width, F32 spinAngle )
{
MatrixF modelview;
dglGetModelview( &modelview );
modelview.transpose();
width *= 0.5;
Point3F points[4];
points[0] = Point3F(-width, 0.0, -width);
points[1] = Point3F(-width, 0.0, width);
points[2] = Point3F( width, 0.0, width);
points[3] = Point3F( width, 0.0, -width);
MatrixF rotMatrix( EulerF( 0.0, spinAngle, 0.0 ) );
for( int i=0; i<4; i++ )
{
rotMatrix.mulP( points[i] );
modelview.mulP( points[i] );
points[i] += position;
}
glBegin(GL_TRIANGLE_FAN);
glTexCoord2f(0.0, 1.0);
glVertex3fv(points[0]);
glTexCoord2f(0.0, 0.0);
glVertex3fv(points[1]);
glTexCoord2f(1.0, 0.0);
glVertex3fv(points[2]);
glTexCoord2f(1.0, 1.0);
glVertex3fv(points[3]);
glEnd();
}
void dglWireCube(const Point3F & extent, const Point3F & center)
{
static Point3F cubePoints[8] =
{
Point3F(-1, -1, -1), Point3F(-1, -1, 1), Point3F(-1, 1, -1), Point3F(-1, 1, 1),
Point3F( 1, -1, -1), Point3F( 1, -1, 1), Point3F( 1, 1, -1), Point3F( 1, 1, 1)
};
static U32 cubeFaces[6][4] =
{
{ 0, 2, 6, 4 }, { 0, 2, 3, 1 }, { 0, 1, 5, 4 },
{ 3, 2, 6, 7 }, { 7, 6, 4, 5 }, { 3, 7, 5, 1 }
};
glDisable(GL_CULL_FACE);
for (S32 i = 0; i < 6; i++)
{
glBegin(GL_LINE_LOOP);
for(int vert = 0; vert < 4; vert++)
{
int idx = cubeFaces[i][vert];
glVertex3f(cubePoints[idx].x * extent.x + center.x,
cubePoints[idx].y * extent.y + center.y,
cubePoints[idx].z * extent.z + center.z);
}
glEnd();
}
}
void dglSolidCube(const Point3F & extent, const Point3F & center)
{
static Point3F cubePoints[8] =
{
Point3F(-1, -1, -1), Point3F(-1, -1, 1), Point3F(-1, 1, -1), Point3F(-1, 1, 1),
Point3F( 1, -1, -1), Point3F( 1, -1, 1), Point3F( 1, 1, -1), Point3F( 1, 1, 1)
};
static U32 cubeFaces[6][4] =
{
{ 0, 2, 6, 4 }, { 0, 2, 3, 1 }, { 0, 1, 5, 4 },
{ 3, 2, 6, 7 }, { 7, 6, 4, 5 }, { 3, 7, 5, 1 }
};
for (S32 i = 0; i < 6; i++)
{
glBegin(GL_TRIANGLE_FAN);
for(int vert = 0; vert < 4; vert++)
{
int idx = cubeFaces[i][vert];
glVertex3f(cubePoints[idx].x * extent.x + center.x,
cubePoints[idx].y * extent.y + center.y,
cubePoints[idx].z * extent.z + center.z);
}
glEnd();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -