C++ 如何将stb_truetype位图加载到和OpenGL纹理中
我有以下代码从std::wstring创建位图,然后使用它保存到图像中C++ 如何将stb_truetype位图加载到和OpenGL纹理中,c++,opengl,bitmap,freetype,C++,Opengl,Bitmap,Freetype,我有以下代码从std::wstring创建位图,然后使用它保存到图像中 #include <stb_image_write.h> #include <stb_truetype.h> unsigned char buffer[24 << 20]; stbtt_fontinfo font; fread(buffer, 1, 1000000, fopen("../assets/fonts/unibody_8.ttf", "rb&qu
#include <stb_image_write.h>
#include <stb_truetype.h>
unsigned char buffer[24 << 20];
stbtt_fontinfo font;
fread(buffer, 1, 1000000, fopen("../assets/fonts/unibody_8.ttf", "rb"));
stbtt_InitFont(&font, buffer, 0);
float scale = stbtt_ScaleForPixelHeight(&font, 48 * 2);
int ascent, descent;
stbtt_GetFontVMetrics(&font, &ascent, &descent, 0);
int baseline = (int)(ascent * scale);
int width = 0;
for (const auto &character : content) {
int advance, leftSideBearing;
stbtt_GetCodepointHMetrics(&font, character, &advance, &leftSideBearing);
texture.width += advance * scale;
}
int height = (ascent + (descent * -1)) * scale;
std::vector<unsigned char> pixels(
(size_t)(texture.width * texture.height), (unsigned char)0);
float xpos = 0.0f;
int characterIndex = 0;
while (content[characterIndex]) {
int advance, lsb, x0, y0, x1, y1;
float x_shift = xpos - (float)floor(xpos);
stbtt_GetCodepointHMetrics(
&font, content[characterIndex], &advance, &lsb);
stbtt_GetCodepointBitmapBoxSubpixel(
&font,
content[characterIndex],
scale,
scale,
x_shift,
0,
&x0,
&y0,
&x1,
&y1);
auto stride = width * (baseline + y0) + (int)xpos + x0;
stbtt_MakeCodepointBitmapSubpixel(
&font,
&pixels.at(0) + stride,
x1 - x0,
y1 - y0,
texture.width,
scale,
scale,
x_shift,
0,
content[characterIndex]);
xpos += (advance * scale);
if (content[characterIndex + 1]) {
int kernAdvance = stbtt_GetCodepointKernAdvance(
&font, content[characterIndex], content[characterIndex + 1]);
xpos += scale * kernAdvance;
}
++characterIndex;
}
// This step works fine, this means that the data in pixels is good
stbi_write_png("image.png", width, height, 1, pixels.data(), 0);
我试图捕获异常,但程序只是静静地崩溃了,所以我不知道如何处理它。这
你告诉德国劳埃德船级社每像素32位,红、绿、蓝和阿尔法各8位。因此,GL将读取比您提供的内存多4倍的内存,读取超过缓冲区的末尾,如果您幸运的话,会在以后的某个时间由于某些分段错误而导致应用程序崩溃
您没有指定正在使用的总账版本。对于现代GL,可以使用GL_RED
作为纹理格式,并直接通过着色器或纹理旋转设置处理到RGBA的转换。对于古老的传统GL,您可能必须使用GL\u亮度
格式
您还必须注意,GL的默认解包行对齐方式为4字节,因此,如果宽度不是4的倍数,您还必须显式设置glPixelStore(GL\u解包\u对齐方式,1)
,以匹配数据对齐方式
uint32_t id = 0;
glGenTextures(1, &id);
glBindTexture(GL_TEXTURE_2D, id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// This crashes the application, I guess it's because the data in pixels is not valid for an OpenGL texture
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA,
width,
height,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
pixels.data());
std::vector<unsigned char> pixels(
(size_t)(texture.width * texture.height), (unsigned char)0);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA,
width,
height,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
pixels.data());