从数据到OpenGL 2D纹理

3

我是使用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上下文中呈现纹理:

enter image description here

正如您所看到的,它是正确的。

然而,当我尝试使用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


这里有很多代码,但你并没有清楚地说明问题。 - Weather Vane
由于您对a的文本呈现似乎是正确的(取决于字体),这是否更多地涉及位图而不是字体的问题? - Weather Vane
当我复制图像并将其粘贴到右侧时,它看起来不太像一条蛇,更像是一个扭曲的 a - Weather Vane
1个回答

6
通常每行的字节数应该是宽度和每像素字节数的倍数。但有些2D光栅化软件需要额外的空间(用于对齐)。从一行跳到另一行称为步幅,它可以大于宽度。从您显示的图像来看,位图的步幅似乎大于宽度。
因此,您需要找出步幅是多少,并将位图复制到步幅等于宽度的位图中,或者使用正确的GL_UNPACK_ROW_LENGTH和glPixelStorei。

您真是我的救星,我只需要加入glPixelStorei(GL_UNPACK_ALIGNMENT, 1);就解决了!再次感谢! - Begah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接