从数据到 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.