GetBounds 获取包围盒,ContainsPoint/HitTest 实现精确拾取,SceneDraw 系列完成最终渲染。
| 函数 | 说明 |
|---|---|
int xgeShapeExSceneGetBounds(xge_shape_ex_scene pScene, float fTolerance, xge_rect_t* pBounds) | 轴对齐包围盒 |
int xgeShapeExSceneGetOBB(xge_shape_ex_scene pScene, float fTolerance, xge_vec2_t* pPoints4) | 有向包围盒(4 顶点) |
int xgeShapeExSceneContainsPoint(xge_shape_ex_scene pScene, float fX, float fY, float fTolerance, int* pContains) | 点是否在场景内 |
int xgeShapeExSceneHitTest(xge_shape_ex_scene pScene, float fX, float fY, float fTolerance, xge_shape_ex* ppShape) | 命中测试(返回 Shape) |
int xgeShapeExSceneDraw(xge_shape_ex_scene pScene, float fTolerance) | 绘制场景 |
int xgeShapeExSceneDrawPx(xge_shape_ex_scene pScene, float fTolerance) | 像素对齐绘制 |
int xgeShapeExSceneDrawEx(xge_shape_ex_scene pScene, float fTolerance, const xge_shape_ex_matrix_t* pParentMatrix, float fParentOpacity) | 带父变换绘制 |
int xgeShapeExSceneDrawPxEx(xge_shape_ex_scene pScene, float fTolerance, const xge_shape_ex_matrix_t* pParentMatrix, float fParentOpacity) | 像素对齐 + 父变换 |
gcc -O2 -I. -o ch72.exe ch72_main.c build\xge.lib -lm -lws2_32 -liphlpapi -lgdi32 -luser32 -lshell32 -lopengl32 -lole32 -lwinmm -lavrt
.\ch72.exe
// 获取场景包围盒
xge_rect_t bounds;
xgeShapeExSceneGetBounds(root, 0.25f, &bounds);
// 鼠标点击命中测试
void OnMouseClick(float mx, float my) {
xge_shape_ex hitShape = NULL;
xgeShapeExSceneHitTest(root, mx, my,
0.25f, &hitShape);
if (hitShape) {
// 命中!高亮该 Shape
xgeShapeExStrokeColor(hitShape, 0xFF6B5EFF);
xgeShapeExStrokeWidth(hitShape, 2.0f);
}
}
// 绘制整棵场景树
xgeShapeExSceneDraw(root, 0.25f);
// 嵌套绘制:传入父级累积变换
xge_shape_ex_matrix_t parentMtx;
xgeShapeExMatrixIdentity(&parentMtx);
xgeShapeExSceneDrawEx(child, 0.25f,
&parentMtx, 1.0f);将以下代码保存为 ch72_main.c,编译后运行即可看到鼠标点击拾取 + 高亮效果:
#include "xge.h"
static xge_shape_ex_scene g_root = NULL;
static xge_shape_ex g_pHit = NULL;
static int onFrame(void* pUser) {
(void)pUser;
xgeClear(0x081114FF);
// 获取鼠标位置并做命中测试
float mx, my;
xgeMouseGet(&mx, &my);
xge_shape_ex hit = NULL;
xgeShapeExSceneHitTest(g_root, (float)mx, (float)my,
0.25f, &hit);
g_pHit = hit;
xgeShapeExSceneDraw(g_root, 0.25f);
// 高亮命中的 Shape
if (g_pHit) {
xgeShapeExStrokeColor(g_pHit, 0xFF6B5EFF);
xgeShapeExStrokeWidth(g_pHit, 3.0f);
xgeShapeExDraw(g_pHit, 0.25f);
}
return XGE_OK;
}
int main(void) {
xge_desc_t d = {0};
d.iWidth = 800;
d.iHeight = 600;
d.sTitle = "ch72 - HitTest";
d.iFlags = XGE_INIT_VSYNC;
xgeInit(&d);
// 构建场景:多个图形
xgeShapeExSceneCreate(&g_root);
for (int i = 0; i < 5; i++) {
xge_shape_ex s = NULL;
xgeShapeExCreate(&s);
if (i % 2 == 0)
xgeShapeExAppendCircle(s, 150+i*130, 300, 50, 1);
else
xgeShapeExAppendRect(s,
100+i*130,250, 100,100, 8,8, 1)
unsigned int cols[] = {
0xFF6B5EFF,0xFFB454FF,0x4FD8C2FF,0x7C6BFFFF,0x5EA8FFCC};
xgeShapeExFillColor(s, cols[i]);
xgeShapeExSceneAdd(g_root, s);
xgeShapeExDestroy(s);
}
xgeRun(onFrame, NULL);
xgeShapeExSceneDestroy(g_root);
xgeUnit();
return 0;
}