从 sprite_sheet 坐标创建纹理

Posted

技术标签:

【中文标题】从 sprite_sheet 坐标创建纹理【英文标题】:Create texture from sprite_sheet coordinates 【发布时间】:2016-10-28 20:07:19 【问题描述】:

我有一个 sprite_sheet(示例表):

我作为矢量数据加载,我需要从指定区域制作新纹理。像这样:

const std::vector <char> image_data = LoadPNG("sprite_sheet.png"); // This works.

glMakeTexture([0, 0], [50, 50], configs, image_data) //to display only one sqm.

但我不知道怎么做,因为大多数 GL 函数只能在整个区域中工作,比如 glTexImage2D。

// Only have width and height, the bottomLeft coords is 0, 0 -- I want to change this.
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &(_sprite_sheet.data[0]));

有没有办法在不将完整的 sprite_sheet 作为纹理加载的情况下做到这一点?

OBS:我正在使用 picoPNG 解码 PNG,我可以加载 png,但不能从指定区域制作纹理。

【问题讨论】:

【参考方案1】:

因为你没有显示代码,所以我假设:

char *data; // data of 8-bit per sample RGBA image
int w, h; // size of the image
int sx, sy, sw, sh; // position and size of area you want to crop.

glTexImage2D 确实支持感兴趣的区域。你可以这样做:

glPixelStorei(GL_UNPACK_ROW_LENGTH, w);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // LodePNG tightly packs everything
glTexImage2D(GL_TEXTURE_2D, level, internalFormat, sw, sh, border, format, type, data);

【讨论】:

@ArnaldoBadin:您的编辑建议不正确 - sw 是图块的大小,这是您尝试加载的纹理的宽度。减去sx 没有意义,因为sw 可以大于sx。例如,要裁剪头部朝左的瓷砖,您使用sx = 192, sy = 64, sw = 64, sh = 64,假设 y 轴向下。 从 topLeft (0, 0) 开始裁剪,-> createTexture(64, 64, 128, 128) 通常会显示一个 64x64 的纹理,所以没有这个减法,glTexImage 假设图像大小是 128 , 128 并以 0.5 比例显示 128x128 纹理和错误的纹理。奇怪,所以这个修复了宽度 -x,高度 - y,告诉 GL 我的图像尺寸是 (64, 64) 坐标的 64x64。 等一下,你的64, 64, 128, 128是什么意思?在我的代码中很简单,如果你想要一个 64x64 的纹理然后你传递sw = 64, sh = 64,问题出在哪里? 是的,你说得对,这是对代码的理解……我的 sw 和 sh 是第二个作物坐标。抱歉,我是 GL 和 C++ 的新手 但在这种情况下你应该写sw - sx而不是sx - sw :)

以上是关于从 sprite_sheet 坐标创建纹理的主要内容,如果未能解决你的问题,请参考以下文章

WebGL-五

openGL三维网格坐标,旋转,缩放,灯光设置,纹理读取,模型读取(MFC单文档)

全屏效果的opengl纹理坐标

从帧缓冲区对象读取时,OpenGL 纹理坐标是相反的

✠OpenGL-5-纹理贴图

使用 OpenGL 进行纹理映射后的奇怪结果