Sampler 控制纹理的过滤和寻址方式;UpdateRGBA 支持局部更新纹理像素,适合动态内容。
采样器(Sampler)决定 GPU 如何从纹理中取值:线性过滤(平滑)或最近邻(像素风), 以及 UV 超出 [0,1] 时的寻址模式(Clamp/Repeat/Mirror)。 UpdateRGBA 允许只更新纹理的一个子矩形,避免整张重新上传。
| 函数 | 说明 |
|---|---|
xge_sampler_t xgeSamplerDefault(void) | 获取默认采样器(线性 + Clamp) |
int xgeTextureSetSampler(xge_texture pTexture, const xge_sampler_t* pSampler) | 设置纹理采样器 |
xge_sampler_t xgeTextureGetSampler(xge_texture pTexture) | 获取当前采样器 |
int xgeTextureUpdateRGBA(xge_texture pTexture, int iX, int iY, int iWidth, int iHeight, const void* pPixels, int iStride) | 局部更新像素 |
gcc -O2 -I. -o ch95.exe ch95_main.c build\xge.lib -lm -lws2_32 -liphlpapi -lgdi32 -luser32 -lshell32 -lopengl32 -lole32 -lwinmm -lavrt
.\ch95.exe
// 设置最近邻采样(像素风格)
xge_sampler_t sampler = xgeSamplerDefault();
sampler.iFilter = XGE_FILTER_NEAREST;
sampler.iWrapU = XGE_WRAP_CLAMP;
sampler.iWrapV = XGE_WRAP_CLAMP;
xgeTextureSetSampler(&spriteTex, &sampler);
// 局部更新:只刷新纹理的一小块区域
uint8_t patch[32 * 32 * 4];
// ... 填充 patch 像素 ...
xgeTextureUpdateRGBA(&tex,
64, 64, // 目标 x, y
32, 32, // 宽, 高
patch, 32 * 4); // 像素 + stride
// 平铺寻址(用于背景重复)
sampler.iWrapU = XGE_WRAP_REPEAT;
sampler.iWrapV = XGE_WRAP_REPEAT;
xgeTextureSetSampler(&bgTex, &sampler);将以下代码保存为 ch95_main.c,编译后运行即可看到像素风渲染与局部更新效果:
#include "xge.h"
#include <string.h>
#define TEX_SIZE 64
static xge_texture_t g_tex;
static float g_time = 0.0f;
static xge_font g_font = NULL;
static int onFrame(void* pUser) {
(void)pUser;
xgeClear(0x081114FF);
g_time += 0.016f;
// 局部更新:动态移动的小方块
uint8_t patch[8 * 8 * 4];
memset(patch, 0, sizeof(patch));
for (int i = 0; i < 8*8; i++) {
patch[i*4+0] = 255;
patch[i*4+1] = (uint8_t)(128 + 127*sinf(g_time*3.0f));
patch[i*4+2] = 0;
patch[i*4+3] = 255;
}
int px = (int)(g_time * 20.0f) % (TEX_SIZE - 8);
xgeTextureUpdateRGBA(&g_tex, px, 28, 8, 8,
patch, 8 * 4);
// 放大绘制(像素风)
xgeDraw(&g_tex, 100.0f, 100.0f);
xgeTextDraw(g_font, "NEAREST filter + partial update",
100.0f, 400.0f, 0xFFFFFFFF)
return XGE_OK;
}
int main(void) {
xge_desc_t d = {0};
d.iWidth = 800;
d.iHeight = 600;
d.sTitle = "ch95 - Pixel Art & Partial Update";
d.iFlags = XGE_INIT_VSYNC;
xgeInit(&d);
xgeFontLoad(&g_font, "Roboto.ttf", 18.0f);
// 创建棋盘格纹理
uint8_t pixels[TEX_SIZE * TEX_SIZE * 4];
for (int y = 0; y < TEX_SIZE; y++)
for (int x = 0; x < TEX_SIZE; x++) {
int i = (y * TEX_SIZE + x) * 4;
uint8_t v = ((x/8 + y/8) % 2) ? 200 : 60;
pixels[i] = pixels[i+1] = pixels[i+2] = v;
pixels[i+3] = 255;
}
xgeTextureCreateRGBA(&g_tex, TEX_SIZE, TEX_SIZE, pixels);
// 设置最近邻采样(像素风格)
xge_sampler_t sampler = xgeSamplerDefault();
sampler.iFilter = XGE_FILTER_NEAREST;
sampler.iWrapU = XGE_WRAP_CLAMP;
sampler.iWrapV = XGE_WRAP_CLAMP;
xgeTextureSetSampler(&g_tex, &sampler);
xgeRun(onFrame, NULL);
xgeTextureFree(&g_tex);
xgeFontFree(g_font);
xgeUnit();
return 0;
}