从数据到 OpenGL 二维纹理
From data to OpenGL 2D Texture
我正在使用 OpenGL 3.3 上下文和 GLFW3 进行窗口化。我也在用C。
我正在使用 STB_truetype 将字符栅格化为动态分配的无符号字符。
我从 STB_truetype 中获取数据:
unsigned char ttf_buffer[1<<25];
stbtt_fontinfo font;
fread(ttf_buffer, 1, 1<<25, fopen("Script Thing.ttf", "rb"));
stbtt_InitFont(&font, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer,0));
int w,h, xoff, yoff;
int c = 'C', s = 60;
unsigned char *bitmap = stbtt_GetCodepointBitmap(&font, 0,stbtt_ScaleForPixelHeight(&font, s), c, &w, &h, &xoff,&yoff);
为了确保我拥有正确的数据,我将其打印到控制台:
for(int i = 0; i < h; i++)
{
for(int x = 0; x < w; x++)
{
printf("%c", bitmap[x+i*w]>>5 ? '1' : ' ');
}
printf("\n");
}
然后创建 2D OpenGL 纹理:
glGenTextures(1,&Texture);
glBindTexture(GL_TEXTURE_2D, Texture);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RED, w,h,
0, GL_RED, GL_UNSIGNED_BYTE, NewTemp );
我用 'A' 字符测试了它,我得到:
11111
1111111
111111111
1111111111
11111111111
111111 11111
111111 11111
111111 1111
111111 1111
11111 1111
111111 1111
111111111111 11111
1111111111111111111111
111111111111111111111
111111111111111111111
111111111 1111111111
11111 111111
1111 11111111
11111 11111111
1111 11111111
1111 111 111
1111 111 1111
1111 1111 111
111 1111 111
111 111 111
1111 111 1111
1111 11111111
1111 1111111
1 111
我渲染纹理 OpenGL 上下文:
正如你所见。
但是当我尝试 C 字符时:
11
1111111111
1111111111111
111111111111111
11111111111111111
1111111 111111
111111 11111
111111 1111
11111 1111
11111 11
1111
11111
1111
1111
1111
1111
1111
1111
1111
111
111
1111
1111
111
1111
1111 11
111111 11111
11111111111111111
111111111111
11
其他字符也一样,例如 'X' :
1111 1111
11111 11111
11111 111111
111111 111111
11111 1111111
11111 1111111
11111 1111111
1111 1111111
11111111111
1111111111
11111111
1111111
111111
111111
1111111
11111111
111111111
11111 1111
11111 1111
11111 1111
1111 1111
1111 1111
1111 111
111 1111
111 111
111 1111
11 11111
1111 11111
11 1
知道我可能做错了什么吗?
谢谢。
编辑:
通过添加 glPixelStorei( GL_UNPACK_ALIGNMENT, 1); 修复了它
就在 glTexImage2D 之前。
再次感谢 doron
通常每一行都是宽度和每像素字节数的倍数。但是一些 2D 光栅化软件之后会需要额外的 dead space(用于对齐目的)。从一行到另一行的跳跃称为步幅,可以大于宽度。从您显示的图像来看,您的位图的步幅似乎大于宽度。
所以你要做的就是找出步幅是多少,然后将位图复制到步幅等于宽度的位图中,或者使用 glPixelStorei
和正确的 GL_UNPACK_ROW_LENGTH
.
我正在使用 OpenGL 3.3 上下文和 GLFW3 进行窗口化。我也在用C。 我正在使用 STB_truetype 将字符栅格化为动态分配的无符号字符。
我从 STB_truetype 中获取数据:
unsigned char ttf_buffer[1<<25];
stbtt_fontinfo font;
fread(ttf_buffer, 1, 1<<25, fopen("Script Thing.ttf", "rb"));
stbtt_InitFont(&font, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer,0));
int w,h, xoff, yoff;
int c = 'C', s = 60;
unsigned char *bitmap = stbtt_GetCodepointBitmap(&font, 0,stbtt_ScaleForPixelHeight(&font, s), c, &w, &h, &xoff,&yoff);
为了确保我拥有正确的数据,我将其打印到控制台:
for(int i = 0; i < h; i++)
{
for(int x = 0; x < w; x++)
{
printf("%c", bitmap[x+i*w]>>5 ? '1' : ' ');
}
printf("\n");
}
然后创建 2D OpenGL 纹理:
glGenTextures(1,&Texture);
glBindTexture(GL_TEXTURE_2D, Texture);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RED, w,h,
0, GL_RED, GL_UNSIGNED_BYTE, NewTemp );
我用 'A' 字符测试了它,我得到:
11111
1111111
111111111
1111111111
11111111111
111111 11111
111111 11111
111111 1111
111111 1111
11111 1111
111111 1111
111111111111 11111
1111111111111111111111
111111111111111111111
111111111111111111111
111111111 1111111111
11111 111111
1111 11111111
11111 11111111
1111 11111111
1111 111 111
1111 111 1111
1111 1111 111
111 1111 111
111 111 111
1111 111 1111
1111 11111111
1111 1111111
1 111
我渲染纹理 OpenGL 上下文:
正如你所见。
但是当我尝试 C 字符时:
11
1111111111
1111111111111
111111111111111
11111111111111111
1111111 111111
111111 11111
111111 1111
11111 1111
11111 11
1111
11111
1111
1111
1111
1111
1111
1111
1111
111
111
1111
1111
111
1111
1111 11
111111 11111
11111111111111111
111111111111
11
其他字符也一样,例如 'X' :
1111 1111
11111 11111
11111 111111
111111 111111
11111 1111111
11111 1111111
11111 1111111
1111 1111111
11111111111
1111111111
11111111
1111111
111111
111111
1111111
11111111
111111111
11111 1111
11111 1111
11111 1111
1111 1111
1111 1111
1111 111
111 1111
111 111
111 1111
11 11111
1111 11111
11 1
知道我可能做错了什么吗? 谢谢。
编辑: 通过添加 glPixelStorei( GL_UNPACK_ALIGNMENT, 1); 修复了它 就在 glTexImage2D 之前。 再次感谢 doron
通常每一行都是宽度和每像素字节数的倍数。但是一些 2D 光栅化软件之后会需要额外的 dead space(用于对齐目的)。从一行到另一行的跳跃称为步幅,可以大于宽度。从您显示的图像来看,您的位图的步幅似乎大于宽度。
所以你要做的就是找出步幅是多少,然后将位图复制到步幅等于宽度的位图中,或者使用 glPixelStorei
和正确的 GL_UNPACK_ROW_LENGTH
.