Fixed bug in edge generation (also appears in regular side). Added portal edge detection. Adjusted layer related debug draw.
This commit is contained in:
parent
e238288549
commit
4be11d07f8
@ -420,45 +420,6 @@ static void drawLayerPortals(duDebugDraw* dd, const rcHeightfieldLayer* layer, c
|
||||
}
|
||||
}
|
||||
dd->end();
|
||||
|
||||
|
||||
/* const float h = rcMax(layer->bmax[1]-layer->bmin[1], ch);
|
||||
|
||||
unsigned int pcol = duLerpCol(color,duRGBA(255,255,255,255),64);
|
||||
dd->begin(DU_DRAW_LINES, 2.0f);
|
||||
for (int j = 0; j < layer->nportals; ++j)
|
||||
{
|
||||
const rcHeightfieldLayerPortal* portal = &layer->portals[j];
|
||||
if (portal->dir == 0 || portal->dir == 2)
|
||||
{
|
||||
const int xx = portal->dir == 0 ? (int)portal->pos : (int)portal->pos+1;
|
||||
const float fx = layer->bmin[0] + xx*cs;
|
||||
const float fy = layer->bmin[1];
|
||||
const float fza = layer->bmin[2] + portal->smin*cs;
|
||||
const float fzb = layer->bmin[2] + portal->smax*cs;
|
||||
dd->vertex(fx, fy+h, fza, pcol);
|
||||
dd->vertex(fx, fy+h, fzb, pcol);
|
||||
dd->vertex(fx, fy, fza, pcol);
|
||||
dd->vertex(fx, fy+h, fza, pcol);
|
||||
dd->vertex(fx, fy, fzb, pcol);
|
||||
dd->vertex(fx, fy+h, fzb, pcol);
|
||||
}
|
||||
else if (portal->dir == 3 || portal->dir == 1)
|
||||
{
|
||||
const int yy = portal->dir == 3 ? (int)portal->pos : (int)portal->pos+1;
|
||||
const float fxa = layer->bmin[0] + portal->smin*cs;
|
||||
const float fxb = layer->bmin[0] + portal->smax*cs;
|
||||
const float fy = layer->bmin[1];
|
||||
const float fz = layer->bmin[2] + yy*cs;
|
||||
dd->vertex(fxa, fy+h, fz, pcol);
|
||||
dd->vertex(fxb, fy+h, fz, pcol);
|
||||
dd->vertex(fxa, fy, fz, pcol);
|
||||
dd->vertex(fxa, fy+h, fz, pcol);
|
||||
dd->vertex(fxb, fy, fz, pcol);
|
||||
dd->vertex(fxb, fy+h, fz, pcol);
|
||||
}
|
||||
}
|
||||
dd->end();*/
|
||||
}
|
||||
|
||||
void duDebugDrawHeightfieldLayers(duDebugDraw* dd, const struct rcHeightfieldLayerSet& lset)
|
||||
@ -490,7 +451,7 @@ void duDebugDrawHeightfieldLayers(duDebugDraw* dd, const struct rcHeightfieldLay
|
||||
{
|
||||
const int idx = x+y*w;
|
||||
const int h = (int)layer->heights[idx];
|
||||
if (h == 0xffff) continue;
|
||||
if (h == 0xff) continue;
|
||||
const unsigned char area = layer->areas[idx];
|
||||
|
||||
unsigned int col;
|
||||
@ -548,10 +509,10 @@ void duDebugDrawHeightfieldLayersRegions(duDebugDraw* dd, const struct rcHeightf
|
||||
{
|
||||
const int idx = x+y*w;
|
||||
const int h = (int)layer->heights[idx];
|
||||
if (h == 0xffff) continue;
|
||||
if (h == 0xff) continue;
|
||||
const unsigned char area = layer->regs ? layer->regs[idx]+1 : 1;
|
||||
|
||||
unsigned int col = duLerpCol(color, duIntToCol(area, 255), 128);
|
||||
unsigned int col = duLerpCol(color, duIntToCol(area, 255), 32);
|
||||
|
||||
const float fx = layer->bmin[0] + x*cs;
|
||||
const float fy = layer->bmin[1] + (h+1)*ch;
|
||||
@ -601,8 +562,11 @@ void duDebugDrawLayerContours(duDebugDraw* dd, const struct rcLayerContourSet& l
|
||||
const float bx = orig[0] + vb[0]*cs;
|
||||
const float by = orig[1] + (vb[1]+1+(i&1))*ch;
|
||||
const float bz = orig[2] + vb[2]*cs;
|
||||
dd->vertex(ax,ay,az,color);
|
||||
dd->vertex(bx,by,bz,duDarkenCol(color));
|
||||
unsigned int col = color;
|
||||
if ((va[3] & 0xf) != 0xf)
|
||||
col = duRGBA(255,255,255,128);
|
||||
|
||||
duAppendArrow(dd, ax,ay,az, bx,by,bz, 0.0f, cs*0.5f, col);
|
||||
}
|
||||
}
|
||||
dd->end();
|
||||
@ -619,8 +583,8 @@ void duDebugDrawLayerContours(duDebugDraw* dd, const struct rcLayerContourSet& l
|
||||
const unsigned char* va = &c.verts[j*4];
|
||||
|
||||
color = duDarkenCol(duIntToCol(i, a));
|
||||
if (va[3])
|
||||
color = duRGBA(255,255,255,a);
|
||||
if (va[3] & 0x80)
|
||||
color = duRGBA(255,0,0,255);
|
||||
|
||||
float fx = orig[0] + va[0]*cs;
|
||||
float fy = orig[1] + (va[1]+1+(i&1))*ch;
|
||||
@ -682,13 +646,15 @@ void duDebugDrawLayerPolyMesh(duDebugDraw* dd, const struct rcLayerPolyMesh& lme
|
||||
for (int j = 0; j < nvp; ++j)
|
||||
{
|
||||
if (p[j] == RC_MESH_NULL_IDX) break;
|
||||
if (p[nvp+j] == RC_MESH_NULL_IDX) continue;
|
||||
if (p[nvp+j] & 0x8000) continue;
|
||||
|
||||
int vi[2];
|
||||
vi[0] = p[j];
|
||||
if (j+1 >= nvp || p[j+1] == RC_MESH_NULL_IDX)
|
||||
vi[1] = p[0];
|
||||
else
|
||||
vi[1] = p[j+1];
|
||||
|
||||
for (int k = 0; k < 2; ++k)
|
||||
{
|
||||
const unsigned short* v = &lmesh.verts[vi[k]*3];
|
||||
@ -710,20 +676,25 @@ void duDebugDrawLayerPolyMesh(duDebugDraw* dd, const struct rcLayerPolyMesh& lme
|
||||
for (int j = 0; j < nvp; ++j)
|
||||
{
|
||||
if (p[j] == RC_MESH_NULL_IDX) break;
|
||||
if (p[nvp+j] != RC_MESH_NULL_IDX) continue;
|
||||
if ((p[nvp+j] & 0x8000) == 0) continue;
|
||||
int vi[2];
|
||||
vi[0] = p[j];
|
||||
if (j+1 >= nvp || p[j+1] == RC_MESH_NULL_IDX)
|
||||
vi[1] = p[0];
|
||||
else
|
||||
vi[1] = p[j+1];
|
||||
|
||||
unsigned int col = colb;
|
||||
if ((p[nvp+j] & 0xff) != 0xff)
|
||||
col = duRGBA(255,255,255,128);
|
||||
|
||||
for (int k = 0; k < 2; ++k)
|
||||
{
|
||||
const unsigned short* v = &lmesh.verts[vi[k]*3];
|
||||
const float x = orig[0] + v[0]*cs;
|
||||
const float y = orig[1] + (v[1]+1)*ch + 0.1f;
|
||||
const float z = orig[2] + v[2]*cs;
|
||||
dd->vertex(x, y, z, colb);
|
||||
dd->vertex(x, y, z, col);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1303,15 +1303,27 @@ bool rcBuildLayerContours(rcContext* ctx,
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < temp.nverts; ++i)
|
||||
for (int i = 0, j = temp.nverts-1; i < temp.nverts; j=i++)
|
||||
{
|
||||
bool shouldRemove;
|
||||
unsigned char* v = &temp.verts[i*4];
|
||||
v[1] = getCornerHeight(layer, (int)v[0], (int)v[1], (int)v[2], walkableClimb, shouldRemove);
|
||||
v[3] = shouldRemove ? 1 : 0;
|
||||
unsigned char* dst = &cont.verts[j*4];
|
||||
unsigned char* v = &temp.verts[j*4];
|
||||
unsigned char* vn = &temp.verts[i*4];
|
||||
unsigned char nei = vn[3]; // The neighbour reg is stored at segment vertex of a segment.
|
||||
bool shouldRemove = false;
|
||||
unsigned char h = getCornerHeight(layer, (int)v[0], (int)v[1], (int)v[2], walkableClimb, shouldRemove);
|
||||
|
||||
dst[0] = v[0];
|
||||
dst[1] = h;
|
||||
dst[2] = v[2];
|
||||
|
||||
// Store portal direction and remove status to the fourth component.
|
||||
dst[3] = 0x0f;
|
||||
const int dir = 0xfe - (int)nei;
|
||||
if (dir >= 0 && dir <= 3)
|
||||
dst[3] = (unsigned char)dir;
|
||||
if (shouldRemove)
|
||||
dst[3] |= 0x80;
|
||||
}
|
||||
|
||||
memcpy(cont.verts, temp.verts, sizeof(unsigned char)*4*temp.nverts);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1325,6 +1337,44 @@ bool rcBuildLayerContours(rcContext* ctx,
|
||||
|
||||
|
||||
|
||||
static const int VERTEX_BUCKET_COUNT2 = (1<<8);
|
||||
|
||||
inline int computeVertexHash2(int x, int y, int z)
|
||||
{
|
||||
const unsigned int h1 = 0x8da6b343; // Large multiplicative constants;
|
||||
const unsigned int h2 = 0xd8163841; // here arbitrarily chosen primes
|
||||
const unsigned int h3 = 0xcb1ab31f;
|
||||
unsigned int n = h1 * x + h2 * y + h3 * z;
|
||||
return (int)(n & (VERTEX_BUCKET_COUNT2-1));
|
||||
}
|
||||
|
||||
static unsigned short addVertex(unsigned short x, unsigned short y, unsigned short z,
|
||||
unsigned short* verts, unsigned short* firstVert, unsigned short* nextVert, int& nv)
|
||||
{
|
||||
int bucket = computeVertexHash2(x, 0, z);
|
||||
unsigned short i = firstVert[bucket];
|
||||
|
||||
while (i != RC_MESH_NULL_IDX)
|
||||
{
|
||||
const unsigned short* v = &verts[i*3];
|
||||
if (v[0] == x && v[2] == z && (rcAbs(v[1] - y) <= 2))
|
||||
return i;
|
||||
i = nextVert[i]; // next
|
||||
}
|
||||
|
||||
// Could not find, create new.
|
||||
i = nv; nv++;
|
||||
unsigned short* v = &verts[i*3];
|
||||
v[0] = x;
|
||||
v[1] = y;
|
||||
v[2] = z;
|
||||
nextVert[i] = firstVert[bucket];
|
||||
firstVert[bucket] = i;
|
||||
|
||||
return (unsigned short)i;
|
||||
}
|
||||
|
||||
|
||||
struct rcEdge
|
||||
{
|
||||
unsigned short vert[2];
|
||||
@ -1333,7 +1383,8 @@ struct rcEdge
|
||||
};
|
||||
|
||||
static bool buildMeshAdjacency(unsigned short* polys, const int npolys,
|
||||
const int nverts, const int vertsPerPoly)
|
||||
const unsigned short* verts, const int nverts,
|
||||
const int vertsPerPoly, const rcLayerContourSet& lcset)
|
||||
{
|
||||
// Based on code by Eric Lengyel from:
|
||||
// http://www.terathon.com/code/edges.php
|
||||
@ -1360,6 +1411,7 @@ static bool buildMeshAdjacency(unsigned short* polys, const int npolys,
|
||||
unsigned short* t = &polys[i*vertsPerPoly*2];
|
||||
for (int j = 0; j < vertsPerPoly; ++j)
|
||||
{
|
||||
if (t[j] == RC_MESH_NULL_IDX) break;
|
||||
unsigned short v0 = t[j];
|
||||
unsigned short v1 = (j+1 >= vertsPerPoly || t[j+1] == RC_MESH_NULL_IDX) ? t[0] : t[j+1];
|
||||
if (v0 < v1)
|
||||
@ -1370,7 +1422,7 @@ static bool buildMeshAdjacency(unsigned short* polys, const int npolys,
|
||||
edge.poly[0] = (unsigned short)i;
|
||||
edge.polyEdge[0] = (unsigned short)j;
|
||||
edge.poly[1] = (unsigned short)i;
|
||||
edge.polyEdge[1] = 0;
|
||||
edge.polyEdge[1] = 0xff;
|
||||
// Insert edge
|
||||
nextEdge[edgeCount] = firstEdge[v0];
|
||||
firstEdge[v0] = (unsigned short)edgeCount;
|
||||
@ -1384,10 +1436,12 @@ static bool buildMeshAdjacency(unsigned short* polys, const int npolys,
|
||||
unsigned short* t = &polys[i*vertsPerPoly*2];
|
||||
for (int j = 0; j < vertsPerPoly; ++j)
|
||||
{
|
||||
if (t[j] == RC_MESH_NULL_IDX) break;
|
||||
unsigned short v0 = t[j];
|
||||
unsigned short v1 = (j+1 >= vertsPerPoly || t[j+1] == RC_MESH_NULL_IDX) ? t[0] : t[j+1];
|
||||
if (v0 > v1)
|
||||
{
|
||||
bool found = false;
|
||||
for (unsigned short e = firstEdge[v1]; e != RC_MESH_NULL_IDX; e = nextEdge[e])
|
||||
{
|
||||
rcEdge& edge = edges[e];
|
||||
@ -1395,13 +1449,108 @@ static bool buildMeshAdjacency(unsigned short* polys, const int npolys,
|
||||
{
|
||||
edge.poly[1] = (unsigned short)i;
|
||||
edge.polyEdge[1] = (unsigned short)j;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
// Matching edge not found, it is an open edge, add it.
|
||||
rcEdge& edge = edges[edgeCount];
|
||||
edge.vert[0] = v1;
|
||||
edge.vert[1] = v0;
|
||||
edge.poly[0] = (unsigned short)i;
|
||||
edge.polyEdge[0] = (unsigned short)j;
|
||||
edge.poly[1] = (unsigned short)i;
|
||||
edge.polyEdge[1] = 0xff;
|
||||
// Insert edge
|
||||
nextEdge[edgeCount] = firstEdge[v1];
|
||||
firstEdge[v1] = (unsigned short)edgeCount;
|
||||
edgeCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mark portal edges.
|
||||
for (int i = 0; i < lcset.nconts; ++i)
|
||||
{
|
||||
rcLayerContour& cont = lcset.conts[i];
|
||||
if (cont.nverts < 3)
|
||||
continue;
|
||||
|
||||
for (int j = 0, k = cont.nverts-1; j < cont.nverts; k=j++)
|
||||
{
|
||||
const unsigned char* va = &cont.verts[k*4];
|
||||
const unsigned char* vb = &cont.verts[j*4];
|
||||
const unsigned char dir = va[3] & 0xf;
|
||||
if (dir == 0xf)
|
||||
continue;
|
||||
|
||||
if (dir == 0 || dir == 2)
|
||||
{
|
||||
// Find matching vertical edge
|
||||
const unsigned short x = (unsigned short)va[0];
|
||||
unsigned short zmin = (unsigned short)va[2];
|
||||
unsigned short zmax = (unsigned short)vb[2];
|
||||
if (zmin > zmax)
|
||||
rcSwap(zmin, zmax);
|
||||
for (int i = 0; i < edgeCount; ++i)
|
||||
{
|
||||
rcEdge& e = edges[i];
|
||||
// Skip connected edges.
|
||||
if (e.poly[0] != e.poly[1])
|
||||
continue;
|
||||
const unsigned short* eva = &verts[e.vert[0]*3];
|
||||
const unsigned short* evb = &verts[e.vert[1]*3];
|
||||
if (eva[0] == x && evb[0] == x)
|
||||
{
|
||||
unsigned short ezmin = eva[2];
|
||||
unsigned short ezmax = evb[2];
|
||||
if (ezmin > ezmax)
|
||||
rcSwap(ezmin, ezmax);
|
||||
if (overlapRange(zmin,zmax, ezmin, ezmax))
|
||||
{
|
||||
// Reuse the other polyedge to store dir.
|
||||
e.polyEdge[1] = dir;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Find matching vertical edge
|
||||
const unsigned short z = (unsigned short)va[2];
|
||||
unsigned short xmin = (unsigned short)va[0];
|
||||
unsigned short xmax = (unsigned short)vb[0];
|
||||
if (xmin > xmax)
|
||||
rcSwap(xmin, xmax);
|
||||
for (int i = 0; i < edgeCount; ++i)
|
||||
{
|
||||
rcEdge& e = edges[i];
|
||||
// Skip connected edges.
|
||||
if (e.poly[0] != e.poly[1])
|
||||
continue;
|
||||
const unsigned short* eva = &verts[e.vert[0]*3];
|
||||
const unsigned short* evb = &verts[e.vert[1]*3];
|
||||
if (eva[2] == z && evb[2] == z)
|
||||
{
|
||||
unsigned short exmin = eva[0];
|
||||
unsigned short exmax = evb[0];
|
||||
if (exmin > exmax)
|
||||
rcSwap(exmin, exmax);
|
||||
if (overlapRange(xmin,xmax, exmin, exmax))
|
||||
{
|
||||
// Reuse the other polyedge to store dir.
|
||||
e.polyEdge[1] = dir;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Store adjacency
|
||||
for (int i = 0; i < edgeCount; ++i)
|
||||
{
|
||||
@ -1413,6 +1562,12 @@ static bool buildMeshAdjacency(unsigned short* polys, const int npolys,
|
||||
p0[vertsPerPoly + e.polyEdge[0]] = e.poly[1];
|
||||
p1[vertsPerPoly + e.polyEdge[1]] = e.poly[0];
|
||||
}
|
||||
else if (e.polyEdge[1] != 0xff)
|
||||
{
|
||||
unsigned short* p0 = &polys[e.poly[0]*vertsPerPoly*2];
|
||||
p0[vertsPerPoly + e.polyEdge[0]] = 0x8000 | (unsigned short)e.poly[1];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
rcFree(firstEdge);
|
||||
@ -1422,43 +1577,6 @@ static bool buildMeshAdjacency(unsigned short* polys, const int npolys,
|
||||
}
|
||||
|
||||
|
||||
static const int VERTEX_BUCKET_COUNT2 = (1<<8);
|
||||
|
||||
inline int computeVertexHash2(int x, int y, int z)
|
||||
{
|
||||
const unsigned int h1 = 0x8da6b343; // Large multiplicative constants;
|
||||
const unsigned int h2 = 0xd8163841; // here arbitrarily chosen primes
|
||||
const unsigned int h3 = 0xcb1ab31f;
|
||||
unsigned int n = h1 * x + h2 * y + h3 * z;
|
||||
return (int)(n & (VERTEX_BUCKET_COUNT2-1));
|
||||
}
|
||||
|
||||
static unsigned short addVertex(unsigned short x, unsigned short y, unsigned short z,
|
||||
unsigned short* verts, unsigned short* firstVert, unsigned short* nextVert, int& nv)
|
||||
{
|
||||
int bucket = computeVertexHash2(x, 0, z);
|
||||
unsigned short i = firstVert[bucket];
|
||||
|
||||
while (i != RC_MESH_NULL_IDX)
|
||||
{
|
||||
const unsigned short* v = &verts[i*3];
|
||||
if (v[0] == x && (rcAbs(v[1] - y) <= 2) && v[2] == z)
|
||||
return i;
|
||||
i = nextVert[i]; // next
|
||||
}
|
||||
|
||||
// Could not find, create new.
|
||||
i = nv; nv++;
|
||||
unsigned short* v = &verts[i*3];
|
||||
v[0] = x;
|
||||
v[1] = y;
|
||||
v[2] = z;
|
||||
nextVert[i] = firstVert[bucket];
|
||||
firstVert[bucket] = i;
|
||||
|
||||
return (unsigned short)i;
|
||||
}
|
||||
|
||||
inline int prev(int i, int n) { return i-1 >= 0 ? i-1 : n-1; }
|
||||
inline int next(int i, int n) { return i+1 < n ? i+1 : 0; }
|
||||
|
||||
@ -2140,9 +2258,6 @@ static bool removeVertex(rcContext* ctx, rcLayerPolyMesh& mesh, const unsigned s
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool rcBuildLayerPolyMesh(rcContext* ctx,
|
||||
rcLayerContourSet& lcset,
|
||||
const int maxVertsPerPoly,
|
||||
@ -2278,7 +2393,7 @@ bool rcBuildLayerPolyMesh(rcContext* ctx,
|
||||
const unsigned char* v = &cont.verts[j*4];
|
||||
indices[j] = addVertex((unsigned short)v[0], (unsigned short)v[1], (unsigned short)v[2],
|
||||
mesh.verts, firstVert, nextVert, mesh.nverts);
|
||||
if (v[3])
|
||||
if (v[3] & 0x80)
|
||||
{
|
||||
// This vertex should be removed.
|
||||
vflags[indices[j]] = 1;
|
||||
@ -2387,12 +2502,12 @@ bool rcBuildLayerPolyMesh(rcContext* ctx,
|
||||
}
|
||||
|
||||
// Calculate adjacency.
|
||||
if (!buildMeshAdjacency(mesh.polys, mesh.npolys, mesh.nverts, nvp))
|
||||
if (!buildMeshAdjacency(mesh.polys, mesh.npolys, mesh.verts, mesh.nverts, nvp, lcset))
|
||||
{
|
||||
ctx->log(RC_LOG_ERROR, "rcBuildLayerPolyMesh: Adjacency failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (mesh.nverts > 0xffff)
|
||||
{
|
||||
ctx->log(RC_LOG_ERROR, "rcBuildLayerPolyMesh: The resulting mesh has too many vertices %d (max %d). Data can be corrupted.", mesh.nverts, 0xffff);
|
||||
|
@ -59,6 +59,7 @@ static bool buildMeshAdjacency(unsigned short* polys, const int npolys,
|
||||
unsigned short* t = &polys[i*vertsPerPoly*2];
|
||||
for (int j = 0; j < vertsPerPoly; ++j)
|
||||
{
|
||||
if (t[j] == RC_MESH_NULL_IDX) break;
|
||||
unsigned short v0 = t[j];
|
||||
unsigned short v1 = (j+1 >= vertsPerPoly || t[j+1] == RC_MESH_NULL_IDX) ? t[0] : t[j+1];
|
||||
if (v0 < v1)
|
||||
@ -83,6 +84,7 @@ static bool buildMeshAdjacency(unsigned short* polys, const int npolys,
|
||||
unsigned short* t = &polys[i*vertsPerPoly*2];
|
||||
for (int j = 0; j < vertsPerPoly; ++j)
|
||||
{
|
||||
if (t[j] == RC_MESH_NULL_IDX) break;
|
||||
unsigned short v0 = t[j];
|
||||
unsigned short v1 = (j+1 >= vertsPerPoly || t[j+1] == RC_MESH_NULL_IDX) ? t[0] : t[j+1];
|
||||
if (v0 > v1)
|
||||
|
Binary file not shown.
@ -746,8 +746,8 @@ void Sample_TileMesh::handleRenderOverlay(double* proj, double* model, int* view
|
||||
{
|
||||
char text[32];
|
||||
snprintf(text,32,"Layer %d", i+1);
|
||||
imguiDrawText((int)x+10+1, (int)y-1, IMGUI_ALIGN_LEFT, text, imguiRGBA(0,0,0,128));
|
||||
imguiDrawText((int)x+10, (int)y, IMGUI_ALIGN_LEFT, text, color);
|
||||
imguiDrawRoundedRect(x+10-6,y-6,100,20, 4, duTransCol(color,128));
|
||||
imguiDrawText((int)x+10, (int)y, IMGUI_ALIGN_LEFT, text, imguiRGBA(255,255,255,255));
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user